﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections;
using System.Configuration;

namespace DataAccess
{
   public class SqlHelper
    {
        /// <summary>
        /// 连接字符串
        /// </summary>
       public static readonly string CONN_STRING_NON_DTC = ConfigurationManager.ConnectionStrings["KPIDbContext"].ConnectionString;
        /// <summary>
        /// 哈希表用来存储缓存的参数信息，哈希表可以存储任意类型的参数
        /// Hashtable.Synchronized 线程安全
        /// </summary>
        private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmd">SqlCommand 命令</param>
        /// <param name="conn">已经存在的数据库连接</param>
        /// <param name="trans">数据库事务处理</param>
        /// <param name="cmdType">SqlCommand 命令类型(存储过程，T-SQL)</param>
        /// <param name="cmdText">存储过程名称或者T-SQL语句</param>
        /// <param name="cmdParms">以数组形式提供 sqlCommand 命令中用到的参数</param>
        private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
        {
            if (conn.State != ConnectionState.Open)
            {
                conn.Open();
            }

            cmd.Connection = conn;
            cmd.CommandText = cmdText;

            if (trans != null)
            {
                cmd.Transaction = trans;
            }

            cmd.CommandType = cmdType;

            if (cmdParms != null)
            {
                foreach (SqlParameter parm in cmdParms)
                    cmd.Parameters.Add(parm);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmdType">SqlCommand 命令类型(存储过程，T-SQL)</param>
        /// <param name="cmdText">存储过程名称或者T-SQL语句</param>
        /// <param name="cmdParms">以数组形式提供 sqlCommand 命令中用到的参数</param>
        /// <returns></returns>
        public static int ExecuteNonQuery(CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection _conn = new SqlConnection(CONN_STRING_NON_DTC))
            {
                PrepareCommand(cmd, _conn, null, cmdType, cmdText, cmdParms);
                int val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="trans"></param>
        /// <param name="cmdType"></param>
        /// <param name="cmdText"></param>
        /// <param name="cmdParms"></param>
        /// <returns></returns>
        public static int ExecuteNonQuery(SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
        {
            SqlCommand cmd = new SqlCommand();
            PrepareCommand(cmd, conn, trans, cmdType, cmdText, cmdParms);
            int val = cmd.ExecuteNonQuery();
            cmd.Parameters.Clear();
            return val;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmdType">SqlCommand 命令类型(存储过程，T-SQL)</param>
        /// <param name="cmdText">存储过程名称或者T-SQL语句</param>
        /// <param name="cmdParms">以数组形式提供 sqlCommand 命令中用到的参数</param>
        /// <returns></returns>
        public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
        {
            SqlCommand cmd = new SqlCommand();
            SqlConnection _conn = new SqlConnection(CONN_STRING_NON_DTC);
            try
            {
                PrepareCommand(cmd, _conn, null, cmdType, cmdText, cmdParms);
                SqlDataReader _rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                cmd.Parameters.Clear();
                return _rdr;
            }
            catch
            {
                _conn.Close();
                throw;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmdType">SqlCommand 命令类型(存储过程，T-SQL)</param>
        /// <param name="cmdText">存储过程名称或者T-SQL语句</param>
        /// <param name="cmdParms">以数组形式提供 sqlCommand 命令中用到的参数</param>
        /// <returns></returns>
        public static int ExecuteScalar(CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection _conn = new SqlConnection(CONN_STRING_NON_DTC))
            {
                PrepareCommand(cmd, _conn, null, cmdType, cmdText, cmdParms);
                int val = Convert.ToInt32(cmd.ExecuteScalar());
                cmd.Parameters.Clear();
                return val;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="trans"></param>
        /// <param name="cmdType"></param>
        /// <param name="cmdText"></param>
        /// <param name="cmdParms"></param>
        /// <returns></returns>
        public static int ExecuteScalar(SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
        {
            SqlCommand cmd = new SqlCommand();
            PrepareCommand(cmd, conn, trans, cmdType, cmdText, cmdParms);
            int val = Convert.ToInt32(cmd.ExecuteScalar());
            cmd.Parameters.Clear();
            return val;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmdType"></param>
        /// <param name="cmdText"></param>
        /// <param name="cmdParms"></param>
        /// <returns></returns>
        public static DataTable GetDataSet(CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
        {
            SqlCommand cmd = new SqlCommand();
            DataSet ds = new DataSet();
            using (SqlConnection conn = new SqlConnection(CONN_STRING_NON_DTC))
            {
                PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
                SqlDataAdapter cmdDa = new SqlDataAdapter(cmd);
                cmdDa.Fill(ds);
                cmdDa.Dispose();
                cmd.Parameters.Clear();
                return ds.Tables[0];
            }
        }
        /// <summary>
        /// 分页（存储过程） 用法例如下：
        /// </summary>
        /// <param>表名(注意：可以多表链接)</param>
        /// <param>需要返回的列</param>
        /// <param>主键</param>
        /// <param>排序的字段名</param>
        /// <param>页尺寸</param>
        /// <param>页码</param>
        /// <param>查询到的记录数</param>
        /// <param>设置排序类型, desc、asc</param>
        /// <param>查询条件 (注意: 不要加 where)</param>
        /// <returns></returns>
        public static DataTable DbPager(
            string tblName,
            string strGetFields,
            string PkeyfldName,
            string OrderfldName,
            int PageSize,
            int PageIndex,
            out int doCount,
            string OrderType,
            string strWhere)
        {
            SqlConnection con = new SqlConnection(CONN_STRING_NON_DTC);
            SqlDataAdapter da = new SqlDataAdapter("DbPager", con);
            da.SelectCommand.CommandType = CommandType.StoredProcedure;
            da.SelectCommand.Parameters.Add(new SqlParameter("@tblName", tblName));
            da.SelectCommand.Parameters.Add(new SqlParameter("@strGetFields", strGetFields));
            da.SelectCommand.Parameters.Add(new SqlParameter("@PkeyfldName", PkeyfldName));
            da.SelectCommand.Parameters.Add(new SqlParameter("@OrderfldName", OrderfldName));
            da.SelectCommand.Parameters.Add(new SqlParameter("@PageSize", PageSize));
            da.SelectCommand.Parameters.Add(new SqlParameter("@PageIndex", PageIndex));
            da.SelectCommand.Parameters.Add("@doCount", SqlDbType.Int);
            da.SelectCommand.Parameters["@doCount"].Direction = ParameterDirection.Output;
            da.SelectCommand.Parameters.Add(new SqlParameter("@OrderType", OrderType));
            da.SelectCommand.Parameters.Add(new SqlParameter("@strWhere", strWhere));
            DataSet ds = new DataSet();
            da.Fill(ds);
            doCount = Convert.ToInt32(da.SelectCommand.Parameters["@doCount"].Value);
            return ds.Tables[0];
        }
    }
}
